﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AppLimit.CloudComputing.SharpBox;
using AppLimit.CloudComputing.SharpBox.StorageProvider.BoxNet;
using AppLimit.CloudComputing.SharpBox.StorageProvider.DropBox;
using AppLimit.CloudComputing.SharpBox.Common.IO;
using System.IO;
using ProtoBuf;
using System.Runtime.Serialization.Formatters.Binary;

namespace DataStorage
{
    public class CloudRepository
    {
        /// <summary>
        /// Connect to Storage Provider. Assumes an already authenticated storage provider. I.e. AuthenticateProvider method has been called.
        /// </summary>
        /// <returns></returns>
        public static CloudStorage ConnectStorage()
        {
            //// Creating the cloudstorage object
            //CloudStorage dropBoxStorage = new CloudStorage();

            //// get the configuration for dropbox 
            //var dropBoxConfig = CloudStorage.GetCloudConfigurationEasy(nSupportedCloudConfigurations.DropBox);

            //// declare an access token
            //ICloudStorageAccessToken accessToken = null;

            //if (File.Exists(Globals.SecurityTokenName))
            //{
            //    using (FileStream fs = File.Open(Globals.SecurityTokenName, FileMode.Open, FileAccess.Read, FileShare.None))
            //    {
            //        accessToken = dropBoxStorage.DeserializeSecurityToken(fs);
            //    }

            //    // open the connection 
            //    var storageToken = dropBoxStorage.Open(dropBoxConfig, accessToken);
            //}

            CloudStorage dropBoxStorage = new CloudStorage();

            //NOT WORKING Box.net
            //ICloudStorageConfiguration configuration;

            //AppLimit.CloudComputing.SharpBox.StorageProvider.GenericNetworkCredentials cred = new AppLimit.CloudComputing.SharpBox.StorageProvider.GenericNetworkCredentials();
            //cred.UserName = "haighis@gmail.com";
            //cred.Password = "dick40four";

            //BoxNetConfiguration config = new BoxNetConfiguration();

            ////// box.net does not support a valid ssl
            //config.TrustUnsecureSSLConnections = true;
            //configuration = config;

            //ICloudStorageAccessToken ValidAccessToken = cred;

            //dropBoxStorage.Open(configuration, ValidAccessToken);
            //Box.net
            SqlRepository r = new SqlRepository();
            User u = r.GetUser();

            //WORKING CloudMe
            AppLimit.CloudComputing.SharpBox.StorageProvider.GenericNetworkCredentials cred = new AppLimit.CloudComputing.SharpBox.StorageProvider.GenericNetworkCredentials();
            cred.UserName = u.Username;
            cred.Password = u.Password;

            ICloudStorageAccessToken ValidAccessToken = cred;

            ICloudStorageConfiguration configuration =
                CloudStorage.GetCloudConfigurationEasy(nSupportedCloudConfigurations.CloudMe, cred);

            dropBoxStorage.Open(configuration, ValidAccessToken);
            //WORKING CloudMe

            return dropBoxStorage;
        }

        public static bool AuthenticateStorage(string username, string password)
        {
            bool isAuth = false;

            try
            {
                CloudStorage dropBoxStorage = new CloudStorage();

                //Box.net

                //WORKING CloudMe
                AppLimit.CloudComputing.SharpBox.StorageProvider.GenericNetworkCredentials cred = new AppLimit.CloudComputing.SharpBox.StorageProvider.GenericNetworkCredentials();
                cred.UserName = username;
                cred.Password = password;

                ICloudStorageAccessToken ValidAccessToken = cred;

                ICloudStorageConfiguration configuration =
                    CloudStorage.GetCloudConfigurationEasy(nSupportedCloudConfigurations.CloudMe, cred);

                dropBoxStorage.Open(configuration, ValidAccessToken);

                ICloudDirectoryEntry root = dropBoxStorage.GetFolder("/booky");

                isAuth = true;

                //WORKING CloudMe

            }
            catch (UnauthorizedAccessException ex)
            {
                                
            }

            return isAuth;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public static bool IsAuthenticatedWithSecurityToken()
        {
            bool isConn = false;

            //if (File.Exists(Globals.SecurityTokenName))
            //{
            //    isConn = true;
            //}

            return true;
        }

        public static void RemoveSecurityToken()
        {
            if (File.Exists(Globals.SecurityTokenName))
            {
                File.Delete(Globals.SecurityTokenName);
            }
        }

        public static void DeleteFromStorage<T>(string filename, StorageFolder folder, T instance)
        {
            var dropBoxStorage = ConnectStorage();

            var publicFolder = dropBoxStorage.GetFolder("/booky/" + folder);

            File.Delete(Globals.LocalDataFolderName + "/" + filename);

            dropBoxStorage.DeleteFileSystemEntry("/booky/" + folder + "/" + filename);
            
            // close the dropbox
            if (dropBoxStorage.IsOpened)
                dropBoxStorage.Close();
        }

        public static void SaveToStorage<T>(string filename, StorageFolder folder, T instance)
        {
            var dropBoxStorage = ConnectStorage();

            var publicFolder = dropBoxStorage.GetFolder("/booky/" + folder.ToString());

            using (var file = File.Create(Globals.LocalDataFolderName + "/" + filename))
            {
                Serializer.Serialize<T>(file, instance ); 
                
                file.Close();

                dropBoxStorage.UploadFile(file.Name, publicFolder);
            }

            // close the dropbox
            if (dropBoxStorage.IsOpened)
                dropBoxStorage.Close();
        }

        public static void CreateCloudFolders()
        {
            //Check if cloud provider is already setup, and if not setup then setup

            var dropBoxStorage = ConnectStorage();

            //Create the top level booky folder
            dropBoxStorage.CreateFolder("/booky");

            //Create the bookmarks folder
            dropBoxStorage.CreateFolder("/booky/" + StorageFolder.bookmarks);

            //Create the tags folder
            dropBoxStorage.CreateFolder("/booky/" + StorageFolder.tags);
           
            //Create the lists folder
            dropBoxStorage.CreateFolder("/booky/" + StorageFolder.lists);

            //Create the booky config folder
            dropBoxStorage.CreateFolder("/booky/" + StorageFolder.config);

            //Create the sync config bin file

            // close the dropbox
            if (dropBoxStorage.IsOpened)
                dropBoxStorage.Close();
        }

        public static void PreFetchAllItems(string folder)
        {
            //Only run this once when we sync at the beginning of the session
            var dropBoxStorage = ConnectStorage();
            // download the testfile from DropBox
            //dropBoxStorage.DownloadFile(publicFolder, "test1.txt", "johntest");

            var publicFolder = dropBoxStorage.GetFolder("/booky/" + folder);

            List<string> fileListDownload = new List<string>();

            // enumerate all child (folder and files)
            foreach (var fof in publicFolder)
            {
                // check if we have a directory
                Boolean bIsDirectory = fof is ICloudDirectoryEntry;

                bool bIsFile = fof is ICloudFileSystemEntry;

                if (bIsFile)
                {
                    fileListDownload.Add(fof.Name);
                }

                // output the info
                //Console.WriteLine("{0}: {1}", bIsDirectory ? "DIR" : "FIL", fof.Name);
            }

            foreach (string item in fileListDownload)
            {
                dropBoxStorage.DownloadFile(publicFolder, item, "/" + folder);
            }
        }

        public static List<Bookmark> GetAllBookmarkItems(string folder)
        {
            //Only run this once when we sync at the beginning of the session
            var dropBoxStorage = ConnectStorage();
            // download the testfile from DropBox
            //dropBoxStorage.DownloadFile(publicFolder, "test1.txt", "johntest");

            // get root
            //ICloudDirectoryEntry root = dropBoxStorage.GetRoot();

            //ICloudDirectoryEntry bookmarksChild = root.GetChild(folder) as ICloudDirectoryEntry;
            
            //root.GetChild();
            //var publicFolder = root.GetChild(folder); //dropBoxStorage.GetFolder("/" + folder);
            // 2. get the path of test root
            //String path = dropBoxStorage.GetFileSystemObjectPath(root);

            ICloudDirectoryEntry publicFolder = dropBoxStorage.GetFolder("/booky/bookmarks");
           
            // bookmarksChild.GetChild("bookmarks");
            
            List<string> fileListDownload = new List<string>();

            //ICloudDirectoryEntry test = dropBoxStorage.GetFolder(path2);

            //ICloudDirectoryEntry r2 = cloudStorage.GetRoot();
            foreach (ICloudFileSystemEntry fof in publicFolder)
            {
                //Console.WriteLine("Enum: {0}", fr2.Name);
                //Assert.AreNotEqual(0, fr2.Name.Length);
                bool bIsFile = fof is ICloudFileSystemEntry;

                if (bIsFile)
                {
                    fileListDownload.Add(fof.Name);
                }
            }

            //// enumerate all child (folder and files)
            //foreach (var fof in publicFolder)
            //{
            //    // check if we have a directory
            //    Boolean bIsDirectory = fof is ICloudDirectoryEntry;

            //    bool bIsFile = fof is ICloudFileSystemEntry;

            //    if (bIsFile)
            //    {
            //        fileListDownload.Add(fof.Name);
            //    }

            //    // output the info
            //    //Console.WriteLine("{0}: {1}", bIsDirectory ? "DIR" : "FIL", fof.Name);
            //}

            foreach (string item in fileListDownload)
            {
                dropBoxStorage.DownloadFile(publicFolder, item, Globals.LocalDataFolderName);
            }

            // close the dropbox
            if (dropBoxStorage.IsOpened)
                dropBoxStorage.Close();

            List<Bookmark> list = new List<Bookmark>();
            
            foreach(var item in fileListDownload)
            {
                using (FileStream fs = File.Open(Globals.LocalDataFolderName + "/" + item, FileMode.Open, FileAccess.Read, FileShare.None))
                {
                    Bookmark b = Serializer.Deserialize<Bookmark>(fs);
                    list.Add(b);
                }
            }

            return list;
        }

        public static List<Tag> GetAllTagItems(string folder)
        {
            //Only run this once when we sync at the beginning of the session
            var dropBoxStorage = ConnectStorage();
            // download the testfile from DropBox
            //dropBoxStorage.DownloadFile(publicFolder, "test1.txt", "johntest");

            // get root
            //ICloudDirectoryEntry root = dropBoxStorage.GetRoot();

            //ICloudDirectoryEntry bookmarksChild = root.GetChild(folder) as ICloudDirectoryEntry;

            //root.GetChild();
            //var publicFolder = root.GetChild(folder); //dropBoxStorage.GetFolder("/" + folder);
            // 2. get the path of test root
            //String path = dropBoxStorage.GetFileSystemObjectPath(root);

            ICloudDirectoryEntry publicFolder = dropBoxStorage.GetFolder("/booky/tags");

            // bookmarksChild.GetChild("bookmarks");

            List<string> fileListDownload = new List<string>();

            //ICloudDirectoryEntry test = dropBoxStorage.GetFolder(path2);

            //ICloudDirectoryEntry r2 = cloudStorage.GetRoot();
            foreach (ICloudFileSystemEntry fof in publicFolder)
            {
                //Console.WriteLine("Enum: {0}", fr2.Name);
                //Assert.AreNotEqual(0, fr2.Name.Length);
                bool bIsFile = fof is ICloudFileSystemEntry;

                if (bIsFile)
                {
                    fileListDownload.Add(fof.Name);
                }
            }

            //// enumerate all child (folder and files)
            //foreach (var fof in publicFolder)
            //{
            //    // check if we have a directory
            //    Boolean bIsDirectory = fof is ICloudDirectoryEntry;

            //    bool bIsFile = fof is ICloudFileSystemEntry;

            //    if (bIsFile)
            //    {
            //        fileListDownload.Add(fof.Name);
            //    }

            //    // output the info
            //    //Console.WriteLine("{0}: {1}", bIsDirectory ? "DIR" : "FIL", fof.Name);
            //}

            foreach (string item in fileListDownload)
            {
                dropBoxStorage.DownloadFile(publicFolder, item, Globals.LocalDataFolderName);
            }

            // close the dropbox
            if (dropBoxStorage.IsOpened)
                dropBoxStorage.Close();

            List<Tag> list = new List<Tag>();

            foreach (var item in fileListDownload)
            {
                using (FileStream fs = File.Open(Globals.LocalDataFolderName + "/" + item, FileMode.Open, FileAccess.Read, FileShare.None))
                {
                    Tag b = Serializer.Deserialize<Tag>(fs);
                    list.Add(b);
                }
            }

            return list;
        }

        public static T LoadFromStorage<T>(string filename, string folder)
        {
            var dropBoxStorage = ConnectStorage();
        
            var publicFolder = dropBoxStorage.GetFolder("/booky/" + folder);

            List<string> fileListDownload = new List<string>();

            dropBoxStorage.DownloadFile(publicFolder, filename, "/" + folder);
            
            // close the dropbox
            if (dropBoxStorage.IsOpened)
                dropBoxStorage.Close();

            using (FileStream fs = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.None))
            {
                //accessToken = dropBoxStorage.DeserializeSecurityToken(fs);
                return Serializer.Deserialize<T>(fs);
            }
        }

        //public static T LoadFromStorage<T>(string filePath)
        //{
        //    //using (IsolatedStorageFile storage = IsolatedStorageFile.GetMachineStoreForAssembly())
        //    //{
        //    //    using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(filePath, FileMode.Open, storage))
        //    //    {
        //    //        return Serializer.Deserialize<T>(stream);
        //    //    }
        //    //}

        //    return null;


        //}
    }
}
